﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Windows.Forms;

namespace HML.Design
{
    /// <summary>
    /// 系统颜色列表控件
    /// </summary>
    [ToolboxItem(false)]
    public class AlphaColorEditorSystemColorControl : ListBox
    {
        #region 属性

        private object[] systemColorValues = null;
        /// <summary>
        /// 系统颜色
        /// </summary>
        public object[] SystemColorValues
        {
            get
            {
                if (this.systemColorValues == null)
                {
                    this.systemColorValues = GetConstantsColor(typeof(SystemColors));
                    Array.Sort((Array)this.systemColorValues, (IComparer)new AlphaColorEditorSystemColorComparer());
                }
                return this.systemColorValues;
            }
        }

        #endregion

        public AlphaColorEditorSystemColorControl()
        {
            this.SuspendLayout();
            this.DrawMode = DrawMode.OwnerDrawFixed;
            this.BorderStyle = BorderStyle.FixedSingle;
            this.IntegralHeight = false;

            this.Items.Clear();
            foreach (var item in this.SystemColorValues)
            {
                this.Items.Add(item);
            }
            this.ResumeLayout();
        }

        #region 重写

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            base.OnDrawItem(e);

            Graphics g = e.Graphics;

            int paddding = 3;
            Color color = (Color)this.Items[e.Index];

            //背景
            e.DrawBackground();

            //颜色块
            SolidBrush color_chunk_sb = new SolidBrush(color);
            Rectangle color_rect = new Rectangle(e.Bounds.X + paddding, e.Bounds.Y + paddding, (int)((e.Bounds.Height - paddding * 2) * 2.5f), e.Bounds.Height - paddding * 2);
            g.FillRectangle(color_chunk_sb, color_rect);
            color_chunk_sb.Dispose();

            //颜色块边框
            Pen color_border_pen = new Pen(Color.Black);
            g.DrawRectangle(color_border_pen, new Rectangle(color_rect.X, color_rect.Y, color_rect.Width - 1, color_rect.Height - 1));
            color_border_pen.Dispose();

            //颜色块文本
            string item_str = color.Name;
            Size item_str_size = g.MeasureString(item_str, e.Font, int.MaxValue, StringFormat.GenericTypographic).ToSize();
            SolidBrush item_str_sb = new SolidBrush(e.ForeColor);
            g.DrawString(item_str, e.Font, item_str_sb, new PointF(color_rect.Right, e.Bounds.Y + (e.Bounds.Height - item_str_size.Height) / 2)); ;
            item_str_sb.Dispose();
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 通过反射获取系统颜色
        /// </summary>
        /// <param name="colorEnumType"></param>
        /// <returns></returns>
        private static object[] GetConstantsColor(Type colorEnumType)
        {
            MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.Static;
            PropertyInfo[] properties = colorEnumType.GetProperties();
            ArrayList arrayList = new ArrayList();
            for (int i = 0; i < properties.Length; ++i)
            {
                PropertyInfo propertyInfo = properties[i];
                if (propertyInfo.PropertyType == typeof(Color))
                {
                    MethodInfo getMethod = propertyInfo.GetGetMethod();
                    if (getMethod != null && (getMethod.Attributes & methodAttributes) == methodAttributes)
                    {
                        arrayList.Add(propertyInfo.GetValue(null, null));
                    }
                }
            }
            return arrayList.ToArray();
        }

        #endregion

        #region 类

        /// <summary>
        /// 系统颜色排序
        /// </summary>
        private class AlphaColorEditorSystemColorComparer : IComparer
        {
            /// <summary>
            /// 根据系统颜色名称进行排序
            /// </summary>
            /// <param name="color1"></param>
            /// <param name="color2"></param>
            /// <returns></returns>
            public int Compare(object color1, object color2)
            {
                return string.Compare(((Color)color1).Name, ((Color)color2).Name, false, CultureInfo.InvariantCulture);
            }

        }

        #endregion
    }


}
